package scfg;

public class RNAStatsObj {

	private String sequence;
	private String structure;
	private String prediction;
	private String predictionX;
	public String GTfoldPrediction;
	private String filename;
	private Integer natCanonicalBasePairs;
	private Integer natWcBasePairs;
	private Integer natWbBasePairs;
	private Integer natBasePairs;
	private Integer predCanonicalBasePairs;
	private Integer predBasePairs;
	private Integer predXCanonicalBasePairs;
	private Integer predXBasePairs;
	private Integer sequenceLength;
	private int[] natPairs;
	private int[] predPairs;
	private int[] predXPairs;
	
	public String getSequence() {
		return sequence;
	}
	public void setSequence(String sequence) {
		this.sequence = sequence;
	}
	public String getNatStructure() {
		return structure;
	}
	public void setNatStructure(String structure) {
		if (structure != null && !structure.equals("null")) {
			this.structure = structure;
			this.natPairs = Grammar.getPairsArraySt(structure);
			this.natBasePairs = null;
			this.natCanonicalBasePairs = null;
		}
	}
	public String getPredStructure() {
		return prediction;
	}
	public void setPredStructure(String structure) {
		if (structure != null && !structure.equals("null")) {
			this.prediction = structure;
			this.predPairs = Grammar.getPairsArraySt(structure);
			this.predBasePairs = null;
			this.predCanonicalBasePairs = null;
		}
	}
	public String getPredXStructure() {
		return predictionX;
	}
	public void setPredXStructure(String structure) {
		if (structure != null && !structure.equals("null")) {
			this.predictionX = structure;
			this.predXPairs = Grammar.getPairsArraySt(structure);
			this.predXBasePairs = null;
			this.predXCanonicalBasePairs = null;
		}
	}
	public Integer getNatCanonicalBasePairs() {
		if (this.natCanonicalBasePairs == null && this.structure != null && !this.structure.equals("null")) {
			this.natCanonicalBasePairs = 0;
			for (int i=0;i<natPairs.length;i++) {
				if (natPairs[i] >= 0) {
					if (isCanonical(sequence.charAt(i), sequence.charAt(natPairs[i]))) {
						this.natCanonicalBasePairs++;
					}
				}
			}
		}
		return natCanonicalBasePairs;
	}
	public Integer getNatWcBasePairs() {
		// TODO
		if (this.natWcBasePairs == null && this.structure != null && !this.structure.equals("null")) {
			this.natWcBasePairs = 0;
			for (int i=0;i<natPairs.length;i++) {
				if (natPairs[i] >= 0) {
					if (isWc(sequence.charAt(i), sequence.charAt(natPairs[i]))) {
						this.natWcBasePairs++;
					}
				}
			}
		}
		return natWcBasePairs;
	}
	public Integer getNatWbBasePairs() {
		// TODO
		if (this.natWbBasePairs == null && this.structure != null && !this.structure.equals("null")) {
			this.natWbBasePairs = 0;
			for (int i=0;i<natPairs.length;i++) {
				if (natPairs[i] >= 0) {
					if (isWb(sequence.charAt(i), sequence.charAt(natPairs[i]))) {
						this.natWbBasePairs++;
					}
				}
			}
		}
		return natWbBasePairs;
	}
	public Integer getNatNonCanonicalBasePairs() {
		return this.getNatBasePairs() - this.getNatCanonicalBasePairs();
	}
	public Integer getNatBasePairs() {
		if (this.natBasePairs == null && this.structure != null && !this.structure.equals("null")) {
			this.natBasePairs = 0;
			for (int i=0;i<natPairs.length;i++) {
				if (natPairs[i] >= 0) {
					this.natBasePairs++;
				}
			}
		}
		return natBasePairs;
	}
	public Integer getPredCanonicalBasePairs() {
		if (this.predCanonicalBasePairs == null && this.prediction != null && !this.prediction.equals("null")) {
			this.predCanonicalBasePairs = 0;
			for (int i=0;i<predPairs.length;i++) {
				if (predPairs[i] >= 0) {
					if (isCanonical(prediction.charAt(i), prediction.charAt(predPairs[i]))) {
						this.predCanonicalBasePairs++;
					}
				}
			}
			
		}
		return predCanonicalBasePairs;
	}
	public Integer getPredBasePairs() {
		if (this.predBasePairs == null && this.prediction != null && !this.prediction.equals("null")) {
			this.predBasePairs = 0;
			for (int i=0;i<predPairs.length;i++) {
				if (predPairs[i] >= 0) {
					this.predBasePairs++;
				}
			}
		}
		return predBasePairs;
	}
	public Integer getPredXCanonicalBasePairs() {
		if (this.predXCanonicalBasePairs == null && this.predictionX != null && !this.predictionX.equals("null")) {
			this.predXCanonicalBasePairs = 0;
			for (int i=0;i<predXPairs.length;i++) {
				if (predXPairs[i] >= 0) {
					if (isCanonical(predictionX.charAt(i), predictionX.charAt(predXPairs[i]))) {
						this.predXCanonicalBasePairs++;
					}
				}
			}
		}
		return predXCanonicalBasePairs;
	}
	public Integer getPredXBasePairs() {
		if (this.predXBasePairs == null && this.predictionX != null && !this.predictionX.equals("null")) {
			this.predXBasePairs = 0;
			for (int i=0;i<predXPairs.length;i++) {
				if (predXPairs[i] >= 0) {
					this.predXBasePairs++;
				}
			}
		}
		return predXBasePairs;
	}
	public Integer getSequenceLength() {
		return sequenceLength;
	}
	
	public RNAStatsObj(String filename, String sequence, String structure, String prediction, String predictionX, String GTfoldPrediction) {
		this.filename = filename;
		this.sequence = sequence;
		this.sequenceLength = sequence.length();
		this.setNatStructure(structure);
		this.setPredStructure(prediction);
		this.setPredXStructure(predictionX);
	}
	private static boolean isCanonical(char a, char b) {
		return isCanonical((a+"")+(b+""));
	}
	private static boolean isCanonical(String pair) {
		return pair.matches("(AU|UA|GC|CG|GU|UG)");
	}
	private static boolean isWc(char a, char b) {
		return isWc((a+"")+(b+""));
	}
	private static boolean isWc(String pair) {
		return pair.matches("(AU|UA|GC|CG)");
	}
	private static boolean isWb(char a, char b) {
		return isWb((a+"")+(b+""));
	}
	private static boolean isWb(String pair) {
		return pair.matches("(GU|UG)");
	}
	public String getFileName() {
		return filename;
	}
	public double getMFEDensityX() {
		if (this.getPredXBasePairs() == null || this.getNatCanonicalBasePairs() == null)
			return 0;
		return (double)this.getNatCanonicalBasePairs()/(double)this.getPredXBasePairs();
	}
}
